//------------------------------------------------------------------------------
#include "application.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDesktopWidget>
#include <QDebug>
#include <QPainter>
#include <QDateTime>
#include <QProcess>
//------------------------------------------------------------------------------
// Constructor/Destructor
//------------------------------------------------------------------------------
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){
	ui->setupUi(this);

	m_aboutDialog = 0;
	m_prefsDialog = 0;

	m_customIconFile = "";
	m_unreadNotifications = 0;

	m_trayMenu = new QMenu();
	m_clearAction = m_trayMenu->addAction(tr("Clear notifications"));
	m_trayMenu->addSeparator();
	m_quitAction = m_trayMenu->addAction(tr("Quit"));

	m_trayIcon = new QSystemTrayIcon(this);
	updateIconPix();
	m_trayIcon->setToolTip(this->windowTitle());
	m_trayIcon->setContextMenu(m_trayMenu);
	m_trayIcon->show();

	// Window geometry
	const QDesktopWidget *desktop = QApplication::desktop();
	QRect screenRect = desktop->screenGeometry(desktop->primaryScreen());
	const QRect &thisRect = geometry();
	this->setGeometry(QRect((screenRect.width()-thisRect.width())/2,(screenRect.height()-thisRect.height())/2,thisRect.width(),thisRect.height()));

	m_notificationsModel = new QStandardItemModel(this);
	m_notificationsModel->setColumnCount(3);
	m_notificationsModel->setSortRole(Qt::DisplayRole);

	QStringList notifHeaderLabels;
	notifHeaderLabels << tr("Date") << tr("Title") << tr("Message");
	m_notificationsModel->setHorizontalHeaderLabels(notifHeaderLabels);

	ui->m_notificationsHistoryTable->setModel(m_notificationsModel);
	ui->m_notificationsHistoryTable->sortByColumn(0, Qt::AscendingOrder);
	ui->m_notificationsHistoryTable->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
	ui->m_notificationsHistoryTable->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);	// Stretch on message column
	connect(ui->m_notificationsHistoryTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(notificationDoubleClicked(QModelIndex)));

	// Signals from UI
	connect(ui->m_actionQuitter, SIGNAL(triggered()), this, SIGNAL(quitRequested()));
	connect(ui->m_clearButton, SIGNAL(released()), this, SLOT(clearNotifications()));
	// Signals from tray icon
	connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
	connect(m_trayIcon, SIGNAL(messageClicked()), this, SLOT(notificationMessageClicked()));
	// Signals tray icon context menu
	connect(m_quitAction, SIGNAL(triggered()), this, SIGNAL(quitRequested()));
	connect(m_clearAction, SIGNAL(triggered()), this, SLOT(clearNotifications()));
}
//------------------------------------------------------------------------------
MainWindow::~MainWindow(){
	delete ui;
}
//------------------------------------------------------------------------------
// Public slots
//------------------------------------------------------------------------------
void MainWindow::displayMessage(STNMessage msg){
	QList<QStandardItem*> row;

	// Date
	QStandardItem* dateItem = new QStandardItem(QDateTime::currentDateTime().toString(Qt::SystemLocaleShortDate));

	// Title whith icon (if given)
	QStandardItem* titleItem;
	if(!msg.getIcon().isEmpty() && QFile(msg.getIcon()).exists())
		titleItem = new QStandardItem(QIcon(msg.getIcon()), msg.getTitle());
	else
		titleItem = new QStandardItem(msg.getTitle());

	// Message
	QStandardItem* messageItem		= new QStandardItem(msg.getMessage());

	// Program command
	dateItem->setData(msg.getProgram(), ProcessCommandRole);
	titleItem->setData(msg.getProgram(), ProcessCommandRole);
	messageItem->setData(msg.getProgram(), ProcessCommandRole);

	row << dateItem << titleItem << messageItem;

	m_notificationsModel->appendRow(row);

	m_unreadNotifications++;
	updateIconPix();

	if(m_trayIcon->isVisible())
		m_trayIcon->showMessage(msg.getTitle(), msg.getMessage(), QSystemTrayIcon::NoIcon, DEFAULT_NOTIFICATION_MESSAGE_DURATION);
}
//------------------------------------------------------------------------------
// Protected methods
//------------------------------------------------------------------------------
void MainWindow::closeEvent(QCloseEvent *evt){
	hide();
	evt->ignore();
}
//------------------------------------------------------------------------------
// Private slots
//------------------------------------------------------------------------------
void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason){
	switch (reason) {
		case QSystemTrayIcon::Trigger:
		case QSystemTrayIcon::DoubleClick:
			if(isVisible())
				hide();
			else{
				clearUnreadNotificationsNumber();
				show();
			}
		break;

		default:
			//qDebug()<<"MainWindow::iconActivated("<<reason<<")";
		break;
	}
}
//------------------------------------------------------------------------------
void MainWindow::notificationDoubleClicked(const QModelIndex &index){
	QString command = m_notificationsModel->data(index, ProcessCommandRole).toString();
	QProcess *proc = new QProcess(this);
	proc->start(command);
}
//------------------------------------------------------------------------------
void MainWindow::notificationMessageClicked(){
	if(!isVisible())
		show();
	else if(isMinimized())
		showNormal();

	raise();
	clearUnreadNotificationsNumber();
}
//------------------------------------------------------------------------------
void MainWindow::on_m_actionAbout_triggered(){
	if(!m_aboutDialog)
		m_aboutDialog = new AboutDialog(this);

	m_aboutDialog->show();
}
//------------------------------------------------------------------------------
void MainWindow::on_m_actionPreferences_triggered(){
	if(!m_prefsDialog)
		m_prefsDialog = new PrefsDialog(this);

	m_prefsDialog->show();
}
//------------------------------------------------------------------------------
// Private methods
//------------------------------------------------------------------------------
void MainWindow::clearUnreadNotificationsNumber(){
	m_unreadNotifications = 0;
	updateIconPix();
}
//------------------------------------------------------------------------------
void MainWindow::clearNotifications(){
	// Clear model
	m_notificationsModel->setRowCount(0);
	// Clear number on tray icon
	clearUnreadNotificationsNumber();
}
//------------------------------------------------------------------------------
void MainWindow::updateIconPix(){
	QPixmap pix;

	// Draw default icon
	if(m_customIconFile.isEmpty() || !QFile(m_customIconFile).exists()){
		pix = QPixmap(DEFAULT_ICON_SIZE);
		QPainter p(&pix);
		p.fillRect(pix.rect(),DEFAULT_ICON_BACKGROUND_COLOR);
	}
	// Draw user custom icon
	else{
		pix = QPixmap(m_customIconFile);
	}

	// Draw unread notifications number
	if(m_unreadNotifications > 0){
		QString text = tr("%1").arg(m_unreadNotifications);
		QPainter p(&pix);

		QFont font;
		if(App.preferences()->contains(CONFIG_KEY_FONT_COLOR))
			font = QFont(App.preferences()->value(CONFIG_KEY_FONT).toString());
		else
			font = DEFAULT_FONT;

		font.setPixelSize(pix.height()*FONT_HEIGHT_FACTOR);
		font.setStyleStrategy(QFont::NoAntialias);

		QRect bnd = QFontMetrics(font).boundingRect(text);

		// Text reduction
		while(
			(bnd.width() > pix.width()-2 || bnd.height() > pix.height()-2) &&
			font.pointSize() > 1
		){
			font.setPointSize(font.pointSize()-1);
			bnd = QFontMetrics(font).boundingRect(text);
		}

		if(App.preferences()->contains(CONFIG_KEY_FONT_COLOR))
			p.setPen(QColor(App.preferences()->value(CONFIG_KEY_FONT_COLOR).toString()));
		else
			p.setPen(DEFAULT_FONT_COLOR);

		p.setFont(font);
		p.drawText(pix.rect(), Qt::AlignCenter, text);
	}

	m_trayIcon->setIcon(QIcon(pix));
}
//------------------------------------------------------------------------------
